package main

import (
	"fmt"
	"gitee.com/shaoninghouse/repodata"
	"github.com/neo4j/neo4j-go-driver/v4/neo4j"
	"log"
	"path/filepath"
)

func createData(session neo4j.Session) {
	url := "https://***.***.com.cn/XXX/x86_64/"
	ri := repodata.NewRepoInfo(repodata.WithWorkspaceRandom("./test"))
	sqlitePath, err := ri.DownloadPrimaryDBFromLink(repodata.Context{}, url)
	if err != nil {
		log.Fatalln(err)
	}
	dbPrimary := filepath.Base(sqlitePath)
	_, _ = session.Run("MERGE (repo:Repository {url: $url, name: 'Example Repo', db_primary: $db_primary})",
		map[string]any{"url": url, "db_primary": dbPrimary})
	sqliteObj, _ := repodata.GetConnectForSqlite(sqlitePath)
	packageList, _ := repodata.GetPackagesWithProvidesAndRequires(sqliteObj)
	for i, packageOne := range packageList {
		log.Println("Package", i, "/", len(packageList), packageOne.Name, packageOne.Version, packageOne.Release)
		// 构建Packages实体
		_, _ = session.Run("MERGE (package:Package {name: $name, version: $version, release: $release, arch: $arch, checksum: $checksum})",
			map[string]any{"name": packageOne.Name, "version": packageOne.Version, "release": packageOne.Release, "arch": packageOne.Arch, "checksum": packageOne.PkgId})
		// 构建 仓库 与 Package 之间的关系
		_, _ = session.Run(`MATCH (repo:Repository {url:  $url, db_primary: $db_primary})
  MATCH (pkg:Package {name: $name, version: $version, release: $release, arch: $arch, checksum: $checksum})
  MERGE (repo)-[:CONTAINS]->(pkg)
  MERGE (pkg)-[:BELONG]->(repo)`,
			map[string]any{"url": url, "db_primary": dbPrimary, "name": packageOne.Name, "version": packageOne.Version, "release": packageOne.Release, "arch": packageOne.Arch, "checksum": packageOne.PkgId})

		for ip, provideOne := range packageOne.Provides {
			// 构建Provide实体
			log.Println("Provides", ip, "/", len(packageOne.Provides), provideOne.Name, provideOne.Flags, provideOne.Version, provideOne.Release)
			_, _ = session.Run("MERGE (provide:Provide {name: $name, flags: $flags, epoch: $epoch, version: $version, release: $release})",
				map[string]any{"name": provideOne.Name, "flags": provideOne.Flags, "epoch": provideOne.Epoch, "version": provideOne.Version, "release": provideOne.Release})
			// 构建 Package 与 Provide 之间的关系
			_, _ = session.Run(`MATCH (pkg:Package {name: $name, version: $version, release: $release, arch: $arch, checksum: $checksum})
  MATCH (provide:Provide {name: $provide_name, flags: $provide_flags, epoch: $provide_epoch, version: $provide_version, release: $provide_release})
  MERGE (pkg)-[:PROVIDE]->(provide)`,
				map[string]any{"name": packageOne.Name, "version": packageOne.Version, "release": packageOne.Release, "arch": packageOne.Arch, "checksum": packageOne.PkgId,
					"provide_name": provideOne.Name, "provide_flags": provideOne.Flags, "provide_epoch": provideOne.Epoch, "provide_version": provideOne.Version, "provide_release": provideOne.Release})
		}
		for ir, requireOne := range packageOne.Requires {
			// 构建Require实体
			log.Println("Require", ir, "/", len(packageOne.Requires), requireOne.Name, requireOne.Flags, requireOne.Version, requireOne.Release)
			_, _ = session.Run("MERGE (require:Require {name: $name, flags: $flags, epoch: $epoch, version: $version, release: $release})",
				map[string]any{"name": requireOne.Name, "flags": requireOne.Flags, "epoch": requireOne.Epoch, "version": requireOne.Version, "release": requireOne.Release})
			_, _ = session.Run(`MATCH (pkg:Package {name: $name, version: $version, release: $release, arch: $arch, checksum: $checksum})
  MATCH (require:Require {name: $require_name, flags: $require_flags, epoch: $require_epoch, version: $require_version, release: $require_release})
  MERGE (pkg)-[:REQUIRE]->(require)`,
				map[string]any{"name": packageOne.Name, "version": packageOne.Version, "release": packageOne.Release, "arch": packageOne.Arch, "checksum": packageOne.PkgId,
					"require_name": requireOne.Name, "require_flags": requireOne.Flags, "require_epoch": requireOne.Epoch, "require_version": requireOne.Version, "require_release": requireOne.Release})
		}
	}

}

func main() {
	// 设置连接信息
	uri := "bolt://***.***.***.***:7687/"
	username := "neo4j"
	password := "***"

	// 创建驱动
	driver, err := neo4j.NewDriver(uri, neo4j.BasicAuth(username, password, ""))
	if err != nil {
		log.Fatalf("Failed to create Neo4j driver: %v", err)
	}
	defer driver.Close()

	// 创建会话
	session := driver.NewSession(neo4j.SessionConfig{AccessMode: neo4j.AccessModeWrite})
	defer session.Close()

	// 创建节点和关系
	createData(session)

	fmt.Println("Data created successfully!")
}
